<script setup>
import draggable from "vuedraggable";
import { componentList } from "../../components/config";
import { debounce } from "@/utils";
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => {
      return [];
    },
  },
  select: {
    type: String,
    default: "",
  },
  parent: {
    type: Object,
  },
});

const emits = defineEmits(["update:modelValue", "update:select", "change"]);
const modelValueModel = computed({
  get() {
    return props.modelValue ?? [];
  },
  set(newValue) {
    emits("update:modelValue", newValue);
  }
})
const importConfig = inject("importConfig"),
  original = inject("original"),
  deleteComponent = inject("deleteComponent"),
  showDrawer = inject("showDrawer"),
  addComponent = inject("addComponent"),
  drag = ref(false);

const dragOptions = {
  animation: 200,
  group: "description",
  disabled: false,
  ghostClass: "ghost",
  scroll: true,
};

const currentIndex = computed({
  get: () => {
    return props.select;
  },
  set: (value) => {
    emits("update:select", value);
  },
});

const components = computed(() => {
  return getComponentTypes(componentList, {});
});

const getComponentTypes = (list, types) => {
  let _types = types;
  for (let i = 0; i < list.length; i++) {
    if (list[i].type) {
      _types[list[i].type] = list[i];
    }
    if (list[i].components) {
      _types = getComponentTypes(list[i].components, _types);
    }
  }
  return _types;
};

// 选中节点
const selectNode = (uid) => {
  currentIndex.value = uid;
};

// 节点展开收起
const collapseTab = (element) => {
  element.open = !element.open;
};

// 导出配置
const expandConfig = ($el) => {
  importConfig({ name: $el.name, comConfig: JSON.stringify($el), icon: "" });
};

// 复制配置
const copyConfig = ($el) => {
  console.log('[ $el ]', $el)
  // debugger
  // return
  let { name, type, group } = $el;
  addComponent({ name, type, group }, $el);
};

// 显示隐藏组件
const showHiddenElement = ($el) => {
  $el.pageConfig.$show = $el.pageConfig.$show === false ? true : false;
  onChange();
};

// 删除组件
const onDelete = (uid) => {
  deleteComponent(uid);
};

const autoSorting = debounce(
  () => {
    // 页面背景/普通组件/置底组件/弹窗
    let background = null,
      popup = [],
      preOridinary = [],
      afterOrdinary = [],
      bottomComponnet = null;
    let bottomComponnetIndex = modelValueModel.value.findIndex((item) => {
      return (
        components.value[item.type] &&
        components.value[item.type].bottom === true
      );
    });
    console.log('[ bottomComponnetIndex ]', bottomComponnetIndex)
    bottomComponnet = modelValueModel.value[bottomComponnetIndex];
    for (let i = 0; i < modelValueModel.value.length; i++) {
      if (i === bottomComponnetIndex) continue;
      let type = modelValueModel.value[i].type;
      let positionType = modelValueModel.value[i].pageConfig.$positionType;
      if (type === "Popup" || modelValueModel.value[i].pageConfig.$mode === "popup") {
        popup.push(modelValueModel.value[i]);
      }
      else if (
        type === "Background" ||
        modelValueModel.value[i].pageConfig.$mode === "background"
      )
        background = modelValueModel.value[i];
      else if (i < bottomComponnetIndex) preOridinary.push(modelValueModel.value[i]);
      else if (positionType === "relative" || !positionType)
        preOridinary.push(modelValueModel.value[i]);
      else if (i > bottomComponnetIndex)
        afterOrdinary.push(modelValueModel.value[i]);
    }
    emits(
      "update:modelValue",
      (background ? [background] : [])
        .concat(preOridinary)
        .concat(bottomComponnet ? [bottomComponnet] : [])
        .concat(afterOrdinary)
        .concat(popup)
    );
    emits("change");
  },
  300,
  false
);

// 组件拖拽排序
const changeSort = (obj) => {
  if (obj.oldIndex > obj.newIndex) {
    modelValueModel.value.splice(obj.newIndex, 0, modelValueModel.value[obj.oldIndex]);
    modelValueModel.value.splice(obj.oldIndex + 1, 1);
  } else {
    modelValueModel.value.splice(
      obj.newIndex + 1,
      0,
      modelValueModel.value[obj.oldIndex]
    );
    modelValueModel.value.splice(obj.oldIndex, 1);
  }
  console.log('[ modelValueModel.value-2 ]', modelValueModel.value)
  autoSorting();
};

const onChange = () => {
  emits("update:modelValue", modelValueModel.value);
  emits("change");
};
</script>
<template>
  <draggable :model-value="modelValueModel" tag="transition-group" :component-data="{
    tag: 'div',
    type: 'transition-group',
    name: !drag ? 'flip-list' : null,
  }" item-key="key" v-bind="dragOptions" @update="changeSort" @start="drag = true" @end="drag = false">
    <template #item="{ element, index }">
      <div class="sort-item_container">
        <div class="sort-item" :class="{
          active: select == element.uid,
          hidden:
            element.type !== 'Popup' &&
            element.pageConfig.$mode !== 'popup' &&
            element.pageConfig.$show === false,
        }" @click="selectNode(element.uid)">
          <div class="left-icon">
            <!-- 下拉 -->
            <div class="arrow-icon" v-if="element.group" @click.stop="collapseTab(element, index)">
              <el-icon :style="{
                transform: `rotate(${element.open ? '180deg' : '0deg'})`,
              }">
                <ArrowDown />
              </el-icon>
            </div>
          </div>
          <div class="sort-item_inner">
            <div class="sort-item_name">{{ element.name }}</div>
          </div>
          <el-popover placement="right" :width="120" trigger="hover" :show-arrow="false"
            popper-class="right-menu_popover">
            <template #reference>
              <div class="right-icon">
                <div>
                  <el-icon>
                    <MoreFilled />
                  </el-icon>
                </div>
              </div>
            </template>
            <el-button plain @click.stop="expandConfig(element)">添加到我的组件</el-button>
            <el-button v-if="!parent" plain @click.stop="copyConfig(element)">复制</el-button>
            <el-button v-if="element.type !== 'Popup' && element.pageConfig.$mode !== 'popup'
              " plain @click.stop="showHiddenElement(element)">{{
    element.pageConfig.$show === false ? "显示" : "隐藏"
  }}</el-button>
            <el-button plain v-if="(original === 'merchant' &&
                !element.pageConfig.$pageFlag &&
                element.pageConfig.$removeable === true) ||
              (original !== 'merchant' &&
                element.pageConfig.$removeable === true)
              " @click.stop="onDelete(element.uid)">删除</el-button>
          </el-popover>
          <div v-if="element.link" class="link-icon">
            <el-icon>
              <Connection />
            </el-icon>
          </div>
        </div>
        <!-- 折叠面板 -->
        <div v-if="element.group" v-show="element.open" class="collapse-container">
          <nested-draggable v-model="element.children" v-model:select="currentIndex" :parent="element"
            @change="onChange" />
        </div>
      </div>
    </template>
    <template #footer>
      <div class="sort-item" v-if="(original !== 'saas' || parent) && !activityReadonly" @click="showDrawer(parent)">
        <div class="sort-item_inner">
          <el-icon>
            <Plus />
          </el-icon>
        </div>
      </div>
    </template>
  </draggable>
</template>
<script>
export default {
  name: "nested-draggable",
};
</script>
<style lang="scss" scoped>
.sort-item_container {
  width: 120px;
  padding: 3px 0;
}

.sort-item {
  cursor: pointer;
  color: var(--el-color-primary);
  background-color: var(--el-color-primary-light-9);
  border-radius: 10px;
  position: relative;

  .left-icon {
    position: absolute;
    left: 2px;
    top: 12px;
    z-index: 1;
  }

  .right-icon {
    display: none;
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-40%);
    z-index: 1;
  }

  .link-icon {
    position: absolute;
    top: 0;
    right: 0;
  }

  &:hover {
    .right-icon {
      display: block;
    }
  }

  &.active {
    background-color: var(--el-color-primary);
    color: var(--el-color-white);
    border-color: var(--el-color-primary);
  }

  &.hidden {
    .sort-item_inner {
      opacity: 0.5;
    }
  }

  &_inner {
    padding: 10px;
    position: relative;
    text-align: center;
  }
}

.collapse-container {
  margin-top: 5px;

  .sort-item {
    margin-left: 10px;
    border-radius: 5px;

    &+.sort-item {
      border-top: 1px solid #ffffff;
    }

    &_inner {
      padding: 5px;
      font-size: 14px;
    }
  }
}

.flip-list-move {
  transition: transform 0.5s;
}

.ghost {
  opacity: 0.5;
}
</style>
<style lang="scss">
.right-menu_popover {
  padding: 0 !important;
  width: 100px !important;
  min-width: auto !important;

  .el-button {
    border: none;
    width: 100%;
    margin-left: 0;

    &+.el-button {
      border-top: 1px solid var(--el-border-color);
    }
  }
}
</style>
